<template>
  <div class="map-container" :style="tableStyle">
    <div id="googleMap"></div>

    <div class="table-data-wrapper">
      <div class="table-data" v-if="showTableTadta">
        <div class="close-table">
          <div>
            <el-select filterable @change="getList" :placeholder="$t('状态')" v-model="status">
              <!-- status: 1: 未完成 3:完成 -->
              <el-option :label="$t('未完成')" :value="1" />
              <el-option :label="$t('已完成')" :value="3" />
            </el-select>
          </div>
          <i class="el-icon-circle-close" @click="showTableTadta = false"></i>
        </div>
        <el-table :height="calTableHeight() - 200" ref="TableRef" :data="tableData">
          <el-table-column
            show-overflow-tooltip
            prop="routePolyLineIndex"
            align="center"
            :label="$t('索引')"
            widht="50"
          />
          <el-table-column show-overflow-tooltip align="center" :label="$t('客人名称')" prop="receiveName">
            <template #default="{ row }">
              <a @click="handleCustomerInfo(row)">{{ row.receiveName }}</a>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip align="center" :label="$t('状态')" widht="50">
            <!-- 1 待配送 2 配送中 3 已完成 (状态2 无用) -->
            <template #default="{ row }">
              <div v-if="row.status == 1" :style="{ color: $randomColor(row.stauts) }">{{ $t('待配送') }}</div>
              <div v-if="row.status == 2" :style="{ color: $randomColor(row.stauts) }">{{ $t('配送中') }}</div>
              <div v-if="row.status == 3" :style="{ color: $randomColor(row.stauts) }">{{ $t('已完成') }}</div>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip align="center" :label="$t('是否显示')" widht="50">
            <template #default="{ row }">
              <el-switch v-model="row.show" @change="(e) => handleShowLine(e, row)" />
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip align="center" :label="$t('操作')" width="50" fixed="right">
            <template #default="{ row }">
              <i class="el-icon-right" @click="handlePoint(row)"></i>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-else class="show-table">
        <i class="el-icon-arrow-right" @click="showTableTadta = true"></i>
      </div>
    </div>
    <CustomerInfo :show.sync="customerInfo.show" :formData="customerInfo.formData" @getList="getList" />
  </div>
</template>

<script>
import { v4 as uuid } from 'uuid'
import { myList, getStartLocation } from '@/api/orderManage/myDispatch'

import Vue from 'vue'
import Marker from './components/marker.vue'
import CustomerInfo from './components/customerInfo.vue'
import { MarkerClusterer } from '@googlemaps/markerclusterer'
export default {
  name: 'googleMap',
  components: { CustomerInfo },
  data() {
    return {
      // status: 1: 未完成 3:完成
      status: 1,
      /**
       * @description 起点marker
       * @type {google.maps.marker.AdvancedMarkerElement}
       * */
      startMarker: null,
      customerInfo: {
        show: false,
        formData: {},
      },
      showTableTadta: true,
      tableData: [],
      map: null,
      /**
       * @type {Array<google.maps.marker.AdvancedMarkerElement>}
       */
      markers: [],
      polylines: [],
      lineColors: ['#32CCBC', '#F6416C', '#28C76F', '#ff7003', '#9708CC'],
      lineColorsIndex: 0,
    }
  },
  computed: {
    /**@returns {string} */
    tableStyle() {
      return {
        '--table-width': this.isMobile() ? `${window.innerWidth - 20}px` : '500px',
      }
    },
  },
  mounted() {
    this.getList()
  },
  methods: {
    resetMap() {
      // 要清空谷歌地图上的所有线（Polyline）和标记（Marker）
      this.markers.map((m) => m.setMap(null))
      this.markers = []
      this.polylines.map((p) => p.setMap(null))
      this.polylines = []
      this.lineColorsIndex = 0
    },
    getList() {
      const { routeId } = this.$route.query
      if (!routeId) return
      myList({ routeId, status: this.status }).then((res) => {
        this.tableData = res.rows.map((item) => {
          return {
            ...item,
            _uuid: uuid(),
            // <!--status 1.待配送 2.配送中 3.已完成 -->
            show: item.status != 3,
          }
        })
        this.initMap()
      })
    },
    handleCustomerInfo(row) {
      const flag = this.$hasPermission('distribution:googleRouteShipments:queryById')
      if (!flag) return
      this.customerInfo.formData = { ...row }
      this.customerInfo.show = true
    },
    handleShowLine(flag, row) {
      const marker = this.markers.find((i) => i._uuid == row._uuid)
      // 隐藏/显示 标记
      if (marker) {
        flag ? marker.setMap(this.map) : marker.setMap(null)
      }
      flag ? row.polyline.setMap(this.map) : row.polyline.setMap(null)
    },
    async handlePoint(row) {
      const {
        encoding: { decodePath },
      } = await google.maps.importLibrary('geometry')
      const pathArr = decodePath(row.routePolyLine)

      const { lat, lng } = pathArr[pathArr.length - 1]
      this.setMapCenter({ lat: lat(), lng: lng() })
      if (this.isMobile()) {
        this.showTableTadta = false
      }
    },
    setMarkerClusterer() {
      // https://googlemaps.github.io/js-markerclusterer/index.html
      // marker数量过多处理
      const markerCluster = new MarkerClusterer({ map: this.map, markers: this.markers })
    },
    /**设置起点marker */
    async setStartMarker(path) {
      const { AdvancedMarkerElement } = await google.maps.importLibrary('marker')
      const img = document.createElement('img')
      img.src = require('@/assets/images/startPoint.png')
      img.className = 'google-start-marker'
      if (this.startMarker) return
      getStartLocation().then((res) => {
        const { latitude, longitude } = res
        const position = { lat: latitude, lng: longitude }
        this.startMarker = new AdvancedMarkerElement({
          map: this.map,
          position,
          content: img,
        })
      })
    },
    async addMarker(params) {
      const { position, index, lineColor, _uuid, polyline, item } = params
      const { AdvancedMarkerElement } = await google.maps.importLibrary('marker')
      /** @type {google.maps.marker.AdvancedMarkerElement}*/
      const marker = await new AdvancedMarkerElement({
        map: this.map,
        position,
        content: this.createComponent(Marker, { lineColor, index, title: index }).$el,
      })
      marker._uuid = _uuid
      marker.addListener('click', () => {
        this.handleCustomerInfo(item)
      })
      this.polylines.push(polyline)
      this.markers.push(marker)
    },
    /**设置中心点位 */
    setMapCenter({ lat, lng }) {
      this.map.setCenter({ lat, lng })
    },
    /**重复设置颜色 */
    getColor() {
      let color
      if (this.lineColorsIndex < this.lineColors.length - 1) {
        color = this.lineColors[this.lineColorsIndex]
        this.lineColorsIndex += 1
      } else {
        this.lineColorsIndex = 0
        color = this.lineColors[this.lineColorsIndex]
        this.lineColorsIndex += 1
      }
      return color
    },
    /**创建组件挂载 */
    createComponent(vueComponents, propsData) {
      // 创建一个临时的 Vue 实例来渲染组件
      const Component = Vue.extend(vueComponents)
      const instance = new Component({
        propsData: { ...propsData },
      })
      instance.$mount()
      return instance
    },
    initMap() {
      this.$nextTick(() => {
        if (!this.map) {
          this.map = new google.maps.Map(document.getElementById('googleMap'), {
            zoom: 10,
            mapId: 'googleMap_ID',
            center: { lat: 35.736156, lng: 139.714222 },
            fullscreenControl: false, // 隐藏全屏控件
            streetViewControl: false, // 隐藏街景控件
            zoomControl: false, // 隐藏缩放控件
            mapTypeControl: false, // 隐藏地图类型控件
          })
          // 确保地图加载完成后再添加路径
          google.maps.event.addListenerOnce(this.map, 'idle', () => {
            // 浏览器默认显示
            if (!this.isMobile()) {
              this.showTableTadta = true
            }
            this.drawLines()
          })
        } else {
          this.drawLines()
        }
      })
    },
    /**绘制线路图 */
    async drawLines() {
      this.resetMap()
      // 无数据不绘制
      if (!this.tableData.length) return
      const {
        encoding: { decodePath },
      } = await google.maps.importLibrary('geometry')
      let self = this
      /**@type {Array} */
      this.tableData = this.tableData.map((i) => {
        return {
          ...i,
          path: decodePath(i.routePolyLine),
        }
      })
      this.tableData.map((item, index) => {
        const routePolylineIndex = item.routePolylineIndex
        const _uuid = item._uuid
        const strokeColor = this.getColor()
        const polyline = new google.maps.Polyline({
          path: item.path,
          geodesic: true,
          strokeColor,
          strokeOpacity: 1.0,
          strokeWeight: routePolylineIndex % 2 == 0 ? 6 : 5,
          zIndex: routePolylineIndex,
        })
        polyline._uuid = _uuid
        item.polyline = polyline
        // status 1.待配送 (2.配送中 无用) 3.已完成
        if (/**待配送*/ this.status == 1) {
          polyline.setMap(this.map)
          // 添加marker
          this.addMarker({
            polyline,
            _uuid: _uuid,
            position: item.path[item.path.length - 1],
            index: item.routePolyLineIndex,
            lineColor: strokeColor,
            item,
          })
        } else if (/**已完成*/ this.status == 3) {
          const color = 'gray'
          polyline.setMap(null)
          polyline.setOptions({
            strokeColor: color,
          })
          // 添加marker
          this.addMarker({
            polyline,
            _uuid: _uuid,
            position: item.path[item.path.length - 1],
            index: item.routePolyLineIndex,
            lineColor: color,
            item,
          })
        }

        polyline.addListener('mouseover', function () {
          this.setOptions({
            strokeColor: '#000',
            zIndex: self.tableData.length,
          })
        })
        polyline.addListener('mouseout', function () {
          this.setOptions({
            strokeColor,
            zIndex: routePolylineIndex,
          })
        })
      })
      // // 调整地图视图以适应路径
      const bounds = new google.maps.LatLngBounds()
      if (self.tableData.length > 0) {
        self.tableData[0].path.forEach((point) => bounds.extend(point))
      }
      this.map.fitBounds(bounds)
      this.setMarkerClusterer()
      this.setStartMarker()
    },
  },
}
</script>
<style lang="scss" scoped>
.map-container {
  width: 100vw;
  height: 100vh;
  position: relative;
  #googleMap {
    width: 100%;
    height: 100%;
  }
  .table-data-wrapper {
    position: absolute;
    left: 10px;
    top: 60px;
    .table-data {
      width: var(--table-width);
      display: flex;
      .el-icon-right {
        font-size: 20px;
        color: #28c76f;
        font-weight: bold;
        cursor: pointer;
      }
      .close-table {
        width: 100%;
        position: absolute;
        top: -40px;
        right: 0;
        // width: 45px;
        // height: 45px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        background: transparent;

        cursor: pointer;
        .el-icon-circle-close {
          border-radius: 5px;
          font-size: 35px;
          color: #422c2ccc;
          background: #f8f8f9;
          box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5);
        }
      }
    }
    .show-table {
      height: 45px;
      font-size: 28px;
      background: #fff;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 3px;
      color: #422c2ccc;
      box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5);
      cursor: pointer;
    }
  }
}
</style>
